import Prelude

data AST = AST [Declaration] deriving (Show)

data Declaration = FunctionDeclaration
  { retval :: Type,
    name   :: Id,
    params :: [Param],
    body   :: Statement } deriving (Show)

data Type = BoolType | IntType | CharType  deriving (Show)

type Id = String

data Param = Param Type Id deriving (Show)

data Statement =
  Assign Expression Expression |
  Return Expression |
  DeclarationStatement Id (Maybe Expression) |
  CallStatement Id [Expression] |
  Seq Statement Statement deriving (Show)

data Expression =
  Variable Id |
  Number (Either Int Double) |
  Call Id [Expression] |
  Sum Expression Expression  deriving (Show)

int = IntType
  
ast1 =
  AST [
    FunctionDeclaration int "fact" [Param int "n"]
      (Return (Variable "n")),
    FunctionDeclaration int "main" [Param int "argc"]
      (Return (Call "fact" [Variable "argc"]))
  ]

main = print ast1